pub mod traffic_light{
    // impl a trait with method ``return time" for traffic light and diiferent 
    // light color return different time. 

    pub enum TrafficLight{
        Red,
        Green,
        Yellow,
    }

    pub trait Light {
        fn return_time(&self) -> u8;
    } 

    impl Light for TrafficLight {
        fn return_time(&self) -> u8 {
            match self {
                TrafficLight::Red => return 60,
                TrafficLight::Green => return 50,
                TrafficLight::Yellow => return 10,
            }
        }
    }
}

pub mod sum_of_slice{
    pub fn sum_of_u32(s : &[u32]) -> Option<u32> {
        let mut sum : Option<u32> = Some(0);
        match sum.as_mut() {
            Some(v) => {
                for item in s {
                    match item > &(u32::MAX - *v) {
                        false =>*v = item +*v,
                        true =>return None,
                    }
                }
                return sum;
            },
            None => None,
        }
    }
}

pub mod graph{
    #[derive(Debug)]
    pub enum Graph{
        Circle(f32), // (radius)
        Square(f32,f32), // (width,height)
        Triangle(f32,f32,f32), // (edge1,edge2,edge3)
    }

    pub trait Area{
        fn get_area(&self) -> f32;
    }

    impl Area for Graph{
        fn get_area(&self) -> f32{
            match &self{
                Graph::Circle(a) => std::f32::consts::PI*a.powi(2),
                Graph::Square(a,b) => a*b,
                Graph::Triangle(a,b,c) => {
                    let p = (a+b+c)/2.0;
                    return (p*(p-a)*(p-b)*(p-c)).sqrt();
                }, 
            }
        }
    }

    pub fn get_area<T:Area>(graph : &T) ->f32 {
        return graph.get_area();
    }

}
